#include "gdt.h"

extern void isr14();

gdt_entry gdt[4];
gdt_ptr _gp;

tss_t my_tss;
char tss_stack[1024];

/* Setup a descriptor in the Global Descriptor Table */
void gdt_set_gate(int num, unsigned long base, unsigned long limit,
                           unsigned char access, unsigned char gran)
{
    /* Setup the descriptor base address */
    gdt[num].base_low = (base & 0xFFFF);
    gdt[num].base_middle = (base >> 16) & 0xFF;
    gdt[num].base_high = (base >> 24) & 0xFF;

    /* Setup the descriptor limits */
    gdt[num].limit_low = (limit & 0xFFFF);
    gdt[num].granularity = ((limit >> 16) & 0x0F);

    /* Finally, set up the granularity and access flags */
    gdt[num].granularity |= (gran & 0xF0);
    gdt[num].access = access;
}

int set_tss_cr3(unsigned int cr3){
	my_tss.cr3=cr3;
}

void init_gdt()
{
    /* Setup the GDT pointer and limit */
    _gp.limit = (sizeof(gdt_entry) * 4) - 1;
    _gp.base = (unsigned)&gdt;

    /* Our NULL descriptor */
    gdt_set_gate(0, 0, 0, 0, 0);


    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xDF);


    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xDF);
    
    my_tss.esp0=(unsigned)tss_stack+1020;
    my_tss.ss0=0x10;
    my_tss.es=0x10;
    my_tss.ss=0x10;
    my_tss.ds=0x10;
    my_tss.fs=0x10;
    my_tss.gs=0x10;
    my_tss.cs=0x08;
    my_tss.eip=(unsigned)isr14;
    my_tss.eflags=0x200;
    
    gdt_set_gate(3, (unsigned)&my_tss, sizeof(tss_t), 0x89, 0x1F);
    
    
    /* Flush out the old GDT and install the new changes! */
    gdt_flush(_gp);
}



 
